package ensemble

import javafx.scene.layout._
import net.oschina.oldpig.snout._
import javafx.scene.control._
import javafx.geometry.Pos
import javafx.application.{Platform, ConditionalFeature, Application}
import javafx.stage.{StageStyle, Stage}
import javafx.scene.{DepthTest, Scene}
import ensemble.controls.{SearchBox, WindowButtons}
import ensemble.pages.Pages


object Ensemble2View extends Ensemble2Controller with ResourceImplicits {

  import FxBuilder._

  val modalDimmer = is[StackPane]
  val rootPane = is[BorderPane]
  val windowResizeButton = is[Region]
  val pageArea = is[Pane]
  val pageToolBar = is[ToolBar]


  object Root extends NodeFactory[BorderPane] {
    override def createInstance = new BorderPane {
      override def layoutChildren() {
        super.layoutChildren()
        windowResizeButton.autosize()
        windowResizeButton.setLayoutX(getWidth - windowResizeButton.getLayoutBounds.getWidth)
        windowResizeButton.setLayoutY(getHeight - windowResizeButton.getLayoutBounds.getHeight)
      }
    }
  }


  object PageTreeToolBar extends NodeFactory[ToolBar] {
    override def createInstance = new ToolBar {
      override def requestLayout() {
        super.requestLayout()
        if (pageToolBar.instance != null && getHeight != pageToolBar.prefHeight(-1)) {
          pageToolBar.setPrefHeight(getHeight)
        }
      }
    }
  }

  object PageArea extends NodeFactory[Pane] {

    import collection.JavaConverters._

    def createInstance = new Pane {
      override def layoutChildren() {
        this.getChildren.asScala.foreach(child => child.resizeRelocate(0, 0, this.getWidth, this.getHeight))
      }
    }
  }

  object BreadcumbBar extends NodeFactory[HBox] {
    def createInstance = new HBox
  }


  var mouseDragOffsetX = 0d
  var mouseDragOffsetY = 0d

  val allButton = is[ToggleButton]
  val samplesButton = is[ToggleButton]
  val docsButton = is[ToggleButton]

  val pageTree = is[TreeView[String]]

  def layerPane(stage: Stage) = stackPane(depthTest := DepthTest.DISABLE) {
    Root(styleClass := "application", id := "root") {
      top := toolBar(prefHeight := 66, minHeight := 66, maxHeight := 66, gridPane.constraints := (0, 0), id := "mainToolBar",
        onMouseClicked := { e =>
          if (e.getClickCount == 2) WindowButtons.toggleMaximized(null)
        },
        onMousePressed := { e => mouseDragOffsetX = e.getSceneX; mouseDragOffsetY = e.getSceneY
        },
        onMouseDragged := { e =>
          if (!WindowButtons.maximized) {
            stage.setX(e.getScreenX - mouseDragOffsetX)
            stage.setY(e.getScreenY - mouseDragOffsetY)
          }
        }
      ) {
        imageView(image := "images/logo.png".relative, hBox.margin := (0, 0, 0, 5))
        region(hBox.hgrow := Priority.ALWAYS)
        button(minSize := (120, 66), prefSize := (120, 66), onAction := onHighlightsButtonClick, id := "highlightsButton")
        button(minSize := (120, 66), prefSize := (120, 66), onAction := onNewButtonClick, id := "newButton")
        region(hBox.hgrow := Priority.ALWAYS)
        imageView(image := "images/search-text.png".relative)
        SearchBox(minHeight := 24, prefSize := (150, 24), maxHeight := 24, hBox.margin := (0, 5, 0, 0), id := "SearchBox");
        WindowButtons(stage)(spacing := 4)
      }
      center := splitPane(maxSize := (Double.MaxValue, Double.MaxValue), gridPane.constraints := (0, 1), dividerPosition := (0, 0.25), id := "page-splitpane") {
        borderPane() {
          top := PageTreeToolBar(minHeight := 29, maxWidth := Double.MaxValue, id := "page-tree-toolbar") {
            val pageButtonGroup = new ToggleGroup
            toggleButton(text := "All", selected := true, toggleGroup := pageButtonGroup, onPropertyInvalidated := (selectedProperty, treeButtonNotifyListener)) as allButton
            toggleButton(text := "Samples", toggleGroup := pageButtonGroup, onPropertyInvalidated := (selectedProperty, treeButtonNotifyListener)) as samplesButton
            toggleButton(text := "Document", toggleGroup := pageButtonGroup) as docsButton
          }
          center := treeView[String](id := "page-tree", maxSize := (Double.MaxValue, Double.MaxValue),
            showRoot := false, editable := false, selectionMode := SelectionMode.SINGLE,
            onPropertyChanged := (selectedItemProperty[String], onPageTreeSelectedChanged),
            root := Pages.root) as pageTree
        }
        borderPane() {
          top := toolBar(minHeight := 29, maxSize := (Double.MaxValue, Control.USE_PREF_SIZE), id := "page-toolbar") {
            button(graphic := "images/back.png".relative, onAction := back, maxHeight := Double.MaxValue)
            button(graphic := "images/forward.png".relative, onAction := forward, maxHeight := Double.MaxValue)
            button(graphic := "images/reload.png".relative, onAction := reload, maxHeight := Double.MaxValue)
            BreadcumbBar(alignment := Pos.CENTER_LEFT, styleClass := "breadcrumb-bar", fillHeight := true)
            region(hBox.hgrow := Priority.ALWAYS)
            button(graphic := "images/settings.png".relative, onAction := showProxyDialog, maxHeight := Double.MaxValue, id := "SettingsButton")
          } as pageToolBar
          center := PageArea(id := "page-area") as pageArea
        }
      }
      unmanaged := region(prefSize := (11, 11), onMousePressed := onResizePressed, onMouseDragged := onResizeDragged) as windowResizeButton
    } as rootPane
    stackPane(visible := false, onMouseClicked := onModalDimmerClick, id := "ModalDimmer") as modalDimmer

  }
}

class Ensemble2 extends Application with ResourceImplicits {
  def start(stage: Stage) {
    val scene = new Scene(Ensemble2View.layerPane(stage), 1020, 700, Platform.isSupported(ConditionalFeature.SCENE3D))
    scene.getStylesheets.add("ensemble2.css".relative)
    stage.setScene(scene)
    stage.initStyle(StageStyle.UNDECORATED)
    stage.show()
  }
}

object Ensemble2 {
  def main(args: Array[String]) {
    Application.launch(classOf[Ensemble2], args: _*)
  }
}
